package com.apimarket.security;

import com.apimarket.entity.SysMenu;
import com.apimarket.entity.SysUser;
import com.apimarket.enums.SecurityEnum;
import com.apimarket.exception.MySecurityException;
import com.apimarket.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description:实现自定义用户认证的核心逻辑
 * @Author ZXR
 * @Date 2021/7/19 19:16
 * @Version 1.0
 */
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private SysUserService sysUserService;
    //传参就是登录时提交的用户名
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if(StringUtils.isEmpty(username))
            throw new MySecurityException(SecurityEnum.USER_NAME_IS_NUM);
        //根据用户名查询用户信息
        SysUser sysUser = sysUserService.selectByName(username);
        if(sysUser==null)
            throw new MySecurityException(SecurityEnum.USER_IS_NULL);
        //这个集合用于存放用户的权限
        List<GrantedAuthority> grantedAuthorities=new ArrayList<>();
        if(sysUser!=null){
            //获取该用户的所有权限
        List<SysMenu> sysMenus = sysUserService.selectMenuListByUser(sysUser.getId());
            /*if(sysMenus==null||sysMenus.size()==0||sysMenus.get(0)==null)
                throw new MySecurityException(SecurityEnum.USER_HAS_NO_PERMISSION);*/
        //声明用户授权
        if(sysMenus!=null && sysMenus.size()!=0 &&sysMenus.get(0)!=null) {
            sysMenus.forEach(sysMenu -> {
                //这里如果用户有对应的菜单权限的话，那么这个菜单权限的permission必须每一个都不为null，否则会报错
                //这里他会自带一个去重
                GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(sysMenu.getPermission());
                grantedAuthorities.add(grantedAuthority);
            });
        }
    }
        //需要构造出 org.springframework.security.core.userdetails.User 对象并返回
        /*这里用它最长的一个构造函数
        User(String username, String password, boolean enabled, boolean accountNonExpired,
         boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities)
        String username：用户名
        String password： 密码
        boolean enabled： 账号是否可用
        boolean accountNonExpired：账号是否过期
        boolean credentialsNonExpired：密码是否过期
        boolean accountNonLocked：账号是否锁定
        Collection<? extends GrantedAuthority> authorities)：用户权限列表
         */
        return new User(sysUser.getUserName(),sysUser.getPassword(),sysUser.getEnabled(),
                sysUser.getNotExpired(),sysUser.getCredentialsNotExpired(),sysUser.getAccountNotLocked(),grantedAuthorities);
    }
}
